//
// Created by Particle_G on 2020/2/29.
//

#ifndef PRIVILEGE_PLUGIN_PRIVILEGE_HPP
#define PRIVILEGE_PLUGIN_PRIVILEGE_HPP

#define AUTH_MASTER 100
#define AUTH_DEVELOPER 90
#define AUTH_OWNER 80
#define AUTH_MANAGER 70
#define AUTH_DEFAULT 40

#define MASTER_ACCOUNT 1135989508
#define MAIN_GROUP 628669530

#include <iostream>
#include <sstream>
#include <regex>
#include <random>
#include <vector>
#include <set>
#include <thread>

#include <cstdint>

#include <bsoncxx/json.hpp>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/document/element.hpp>
#include <bsoncxx/exception/exception.hpp>

#include <mongocxx/exception/bulk_write_exception.hpp>
#include <mongocxx/exception/error_code.hpp>
#include <mongocxx/exception/logic_error.hpp>
#include <mongocxx/exception/operation_exception.hpp>
#include <mongocxx/exception/server_error_code.hpp>

#include <mongocxx/instance.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>

#endif //PRIVILEGE_PLUGIN_PRIVILEGE_HPP

using namespace cq;
using namespace std;
using Message = cq::message::Message;
using MessageSegment = cq::message::MessageSegment;

using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::open_document;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::document;

const vector<string> GROUP_AVAILABLE_COMMANDS = {"#h", "#reboot", "#auth", "#feature"};
const vector<string> SINGLE_AVAILABLE_COMMANDS = {"#h", "#reboot"};

namespace privilege {
    struct keyValue {
        string stringKey = "", stringValue = "";
        int32_t int32Key = 0, int32Value = 0;
        double doubleKey = 0.0, doubleValue = 0.0;
    };

    void InitDB(const mongocxx::database &database, vector<keyValue> &authLevels_vec, vector<keyValue> &enabledFeatures_vec);

    void InitGroup(mongocxx::database database, const vector<keyValue> &enabledFeatures_vec);

    void InitMember(const mongocxx::database &database, const vector<keyValue> &enabledFeatures_vec,
                    const string &groupID_str);

    void InitFeature(const mongocxx::database &database, const vector<keyValue> &enabledFeatures_vec,
                     const string &groupID_str);

    void InitDB(const mongocxx::database &database, vector<keyValue> &authLevels_vec, vector<keyValue> &enabledFeatures_vec) {
        bool initialed = database.has_collection("GlobalConfig");
        if (initialed) {
            bsoncxx::stdx::optional<bsoncxx::document::value> globalConfig_doc =
                    database.collection("GlobalConfig").find_one({});
            if (globalConfig_doc) {
                bsoncxx::array::view authLevels_arr{globalConfig_doc->view()["authLevels"].get_array().value};
                for (const bsoncxx::array::element &authLevels_doc : authLevels_arr) {
                    auto tempAuthLevel_doc = authLevels_doc.get_document().value;
                    keyValue tempKeyValue;
                    stringstream tempSS;
                    tempSS << tempAuthLevel_doc["name"].get_utf8().value;
                    tempSS >> tempKeyValue.stringKey;
                    tempKeyValue.int32Value = tempAuthLevel_doc["level"].get_int32().value;
                    authLevels_vec.push_back(tempKeyValue);
                }
                bsoncxx::array::view enabledFeatures_arr{globalConfig_doc->view()["enabledFeatures"].get_array().value};
                for (const bsoncxx::array::element &enabledFeatures_doc : enabledFeatures_arr) {
                    auto tempEnabledFeatures_doc = enabledFeatures_doc.get_document().value;
                    keyValue tempKeyValue;
                    stringstream tempSS1, tempSS2;
                    tempSS1 << tempEnabledFeatures_doc["name"].get_utf8().value;
                    tempSS2 << tempEnabledFeatures_doc["type"].get_utf8().value;
                    tempKeyValue.stringKey = tempSS1.str(), tempKeyValue.stringValue = tempSS2.str();
                    enabledFeatures_vec.push_back(tempKeyValue);
                }
            } else {
                initialed = false;
            }
        }
        if (!initialed) {
            for (int i = 0; i < 4; ++i) {
                keyValue authLevelKeyValue, enabledFeatureKeyValue;
                switch (i) {
                    case 0 :
                        authLevelKeyValue.stringKey = "Master", authLevelKeyValue.int32Value = 100;
                        enabledFeatureKeyValue.stringKey = "luckLevel", enabledFeatureKeyValue.stringValue = "int32_t";
                        break;
                    case 1 :
                        authLevelKeyValue.stringKey = "Developer", authLevelKeyValue.int32Value = 90;
                        enabledFeatureKeyValue.stringKey = "cash", enabledFeatureKeyValue.stringValue = "int64_t";
                        break;
                    case 2 :
                        authLevelKeyValue.stringKey = "GroupOwner", authLevelKeyValue.int32Value = 80;
                        enabledFeatureKeyValue.stringKey = "deposit", enabledFeatureKeyValue.stringValue = "int64_t";
                        break;
                    default:
                        authLevelKeyValue.stringKey = "GroupManager", authLevelKeyValue.int32Value = 70;
                        enabledFeatureKeyValue.stringKey = "lotteryCode", enabledFeatureKeyValue.stringValue = "utf_8";
                        break;
                }
                authLevels_vec.push_back(authLevelKeyValue);
                enabledFeatures_vec.push_back(enabledFeatureKeyValue);
            }
            auto builder = bsoncxx::builder::stream::document{};
            builder << "authLevels" << open_array
                    << open_document
                    << "name" << "Master"
                    << "level" << AUTH_MASTER
                    << close_document
                    << open_document
                    << "name" << "Developer"
                    << "level" << AUTH_DEVELOPER
                    << close_document
                    << open_document
                    << "name" << "GroupOwner"
                    << "level" << AUTH_OWNER
                    << close_document
                    << open_document
                    << "name" << "GroupManager"
                    << "level" << AUTH_MANAGER
                    << close_document
                    << open_document
                    << "name" << "DefaultMember"
                    << "level" << AUTH_DEFAULT
                    << close_document
                    << close_array;
            builder << "enabledFeatures" << open_array
                    << open_document
                    << "name" << "luckLevel"
                    << "type" << "int32_t"
                    << close_document
                    << open_document
                    << "name" << "cash"
                    << "type" << "int64_t"
                    << close_document
                    << open_document
                    << "name" << "deposit"
                    << "type" << "int64_t"
                    << close_document
                    << open_document
                    << "name" << "lotteryCode"
                    << "type" << "utf_8"
                    << close_document
                    << close_array;
            bsoncxx::document::value initDoc = builder << finalize;
            database.collection("GlobalConfig").insert_one(initDoc.view());
        }

        InitGroup(database, enabledFeatures_vec);
    }

    void InitGroup(mongocxx::database database, const vector<keyValue> &enabledFeatures_vec) {
        vector<Group> realIncludedGroups_vec = get_group_list();
        vector<string> databaseIncludedGroups_vec = database.list_collection_names();
        set<string> realExcludedGroups_set, databaseExcludedGroups_set;
        for (auto &realGroup : realIncludedGroups_vec) {
            //logging::debug("realGroups", to_string(realGroup.group_id));
            realExcludedGroups_set.insert(to_string(realGroup.group_id));
        }
        for (auto &dbGroup : databaseIncludedGroups_vec) {
            if (dbGroup == "GlobalConfig") {
                continue;
            }
            //logging::debug("dbGroup", dbGroup);
            if (realExcludedGroups_set.count(dbGroup) == 1) {
                realExcludedGroups_set.erase(dbGroup);
                InitFeature(database, enabledFeatures_vec, dbGroup);
            } else {
                databaseExcludedGroups_set.insert(dbGroup);
            }
        }
        if (!databaseExcludedGroups_set.empty()) {
            send_group_message(MAIN_GROUP, "数据库更新：移除无效群聊数据");
            for (const auto &it : databaseExcludedGroups_set) {
                //logging::debug("ManagingGroups", "Deleting Group: " + it);
                database.collection(it).drop();
            }
        }
        if (!realExcludedGroups_set.empty()) {
            send_group_message(MAIN_GROUP, "数据库更新：初始化新增群聊数据");
            for (const auto &it : realExcludedGroups_set) {
                //logging::debug("ManagingGroups", "Adding Group: " + it);
                InitMember(database, enabledFeatures_vec, it);
            }
        }
    }

    void InitMember(const mongocxx::database &database, const vector<keyValue> &enabledFeatures_vec,
                    const string &groupID_str) {
        vector<GroupMember> tempGroupMember = get_group_member_list(strtoll(groupID_str.c_str(), nullptr, 10));
        vector<bsoncxx::document::value> groupMemberDocuments;
        groupMemberDocuments.reserve(tempGroupMember.size());
        for (const auto &groupMember : tempGroupMember) {
            auto builder = bsoncxx::builder::stream::document{};
            builder << "userID" << groupMember.user_id
                    << "authLevel" << (groupMember.user_id == MASTER_ACCOUNT ? AUTH_MASTER : AUTH_DEFAULT);
            for (auto &enabledFeature : enabledFeatures_vec) {
                string tempType = enabledFeature.stringValue, tempFeature = enabledFeature.stringKey;
                if (tempType == "int32_t" || tempType == "int64_t") {
                    builder << tempFeature << 0;
                } else if (tempType == "double") {
                    builder << tempFeature << 0.0;
                } else if (tempType == "utf_8") {
                    builder << tempFeature << "";
                }
            }
            groupMemberDocuments.push_back(builder << finalize);
        }
        database.collection(groupID_str).insert_many(groupMemberDocuments);
    }

    void InitFeature(const mongocxx::database &database, const vector<keyValue> &enabledFeatures_vec,
                     const string &groupID_str) {
        bool isUninitialized = false;
        auto memberCursor = database.collection(groupID_str).find({});
        for (const bsoncxx::document::view &memberDoc : memberCursor) {
            for (auto &enabledFeature : enabledFeatures_vec) {
                string tempType = enabledFeature.stringValue, tempFeature = enabledFeature.stringKey;
                try {
                    memberDoc[tempFeature].key();
                } catch (bsoncxx::v_noabi::exception &) {
                    if(!isUninitialized) {
                        isUninitialized = true;
                        send_group_message(MAIN_GROUP, "数据库更新：初始化新增功能数据");
                    }
                    document tempFeatureDoc;
                    if (tempType == "int32_t" || tempType == "int64_t") {
                        tempFeatureDoc << "$set" << open_document << tempFeature << 0 << close_document;
                    } else if (tempType == "double") {
                        tempFeatureDoc << "$set" << open_document << tempFeature << 0.0 << close_document;
                    } else if (tempType == "utf_8") {
                        tempFeatureDoc << "$set" << open_document << tempFeature << "" << close_document;
                    }
                    database.collection(groupID_str).update_one(memberDoc, tempFeatureDoc << finalize);
                }
            }
        }
    }

    namespace group {
        int CommandCheck(const string &command_str, const vector<string> &availableCommands_vec);

        int32_t GetUserAuthLevel(const string &groupID_str, int64_t userID_int, const mongocxx::database &tempDatabase);

        template<typename T>
        void GetUserData(int64_t userID_int, const string &dataKey, T &dataType, mongocxx::collection tempCollection);

        int CommandCheck(const string &command_str, const vector<string> &availableCommands_vec) {
            for (unsigned int i = 0; i < availableCommands_vec.size(); ++i) {
                if (command_str == availableCommands_vec[i]) {
                    return i;
                }
            }
            return -1;
        }

        int32_t
        GetUserAuthLevel(const string &groupID_str, int64_t userID_int, const mongocxx::database &tempDatabase) {
            int32_t authLevel = 0;
            try {
                GetUserData(userID_int, "authLevel", authLevel, tempDatabase.collection(groupID_str));

            } catch (string &) {
                authLevel = -1;
            }
            return authLevel;
        }

        template<typename T>
        void GetUserData(int64_t userID_int, const string &dataKey, T &dataType, mongocxx::collection tempCollection) {
            bsoncxx::stdx::optional<bsoncxx::document::value> userObject = tempCollection.find_one(
                    document{} << "userID" << userID_int << finalize);
            if (userObject) {
                if (typeid(dataType) == typeid(int32_t)) {
                    dataType = userObject->view()[dataKey].get_int32().value;
                } else if (typeid(dataType) == typeid(int64_t)) {
                    dataType = userObject->view()[dataKey].get_int64().value;
                } else if (typeid(dataType) == typeid(double)) {
                    dataType = userObject->view()[dataKey].get_double().value;
                } else if (typeid(dataType) == typeid(string)) {
                    stringstream tempSS;
                    tempSS << userObject->view()[dataKey].get_utf8().value;
                    tempSS >> dataType;
                } else if (typeid(dataType) == typeid(bool)) {
                    dataType = userObject->view()[dataKey].get_int32().value;
                }
            } else {
                string e = "KEY_NOT_FOUND";
                throw e;
            }
        }

        namespace manage {
            void CommandHelp(int64_t groupID_int, unsigned int paramCounts_int);

            void CommandReboot(int64_t groupID_int, const vector<string> &paramList, int32_t authLevel);

            void
            CommandAuth(int64_t groupID_int, int64_t callerID_int, const vector<string> &paramList, int32_t authLevel, const mongocxx::database &tempDatabase);

            void CommandFeature(int64_t groupID_int, int64_t callerID_int, const vector<string> &paramList, int32_t authLevel,
                                const mongocxx::database &tempDatabase, const vector<keyValue> &enabledFeatures_vec);

            void CommandHelp(int64_t groupID_int, unsigned int paramCounts_int) {
                if (paramCounts_int != 1) {
                    try {
                        send_group_message(groupID_int, "参数个数错误！应为: 0 个");
                    } catch (ApiError &e) {
                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                    }
                } else {
                    string responseMessage = "鉴权插件指令列表\n"
                                             "  #auth [-set|-get|-h] [@xxx]\n"
                                             "  #feature [-h|xxx] [@xxx]\n"
                                             "输入指令 + \"-h\" 来获取对应指令的帮助";
                    try {
                        send_group_message(groupID_int, responseMessage);
                    } catch (ApiError &e) {
                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                    }
                }
            }

            void CommandReboot(int64_t groupID_int, const vector<string> &paramList, int32_t authLevel) {
                smatch subMatches;
                switch (paramList.size()) {
                    case 1 :
                        if (authLevel >= AUTH_DEVELOPER) {
                            send_group_message(groupID_int, "正在重启……");
                            system("taskkill /f /t /im CQP.exe");
                        } else {
                            try {
                                send_group_message(groupID_int, "没有足够的权限使用该命令，至少需要：" + to_string(AUTH_DEVELOPER));
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    case 2 :
                        if (regex_match(paramList[1], subMatches, regex(R"((\d{1,3}))"))) {
                            int waitBeforeReboot_int = strtol(subMatches[1].str().c_str(), nullptr, 10);
                            if (authLevel >= AUTH_DEVELOPER) {
                                send_group_message(groupID_int, to_string(waitBeforeReboot_int) + " 秒之后重启……");
                                this_thread::sleep_for(chrono::seconds(waitBeforeReboot_int));
                                system("taskkill /f /t /im CQP.exe");
                            } else {
                                try {
                                    send_group_message(groupID_int, "没有足够的权限使用该命令，至少需要：" + to_string(AUTH_DEVELOPER));
                                } catch (ApiError &e) {
                                    logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                }
                            }
                        } else {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数类型或范围错误");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    default:
                        try {
                            send_group_message(groupID_int, "参数个数错误！应为: [0-1] 个");
                        } catch (ApiError &e) {
                            logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                        }
                        break;
                }
            }

            void
            CommandAuth(int64_t groupID_int, int64_t callerID_int, const vector<string> &paramList, int32_t authLevel,
                        const mongocxx::database &tempDatabase) {
                smatch subMatches;
                switch (paramList.size()) {
                    case 1 :
                        try {
                            send_group_message(groupID_int,
                                               "[CQ:at,qq=" + to_string(callerID_int) + "] 的权限等级为：" +
                                               to_string(authLevel));
                        } catch (ApiError &e) {
                            logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                        }
                        break;
                    case 2 :
                        if (paramList[1] == "-h") {
                            string responseMessage = "#auth指令帮助：\n"
                                                     "  [-set|-get {num}] 设置|获取权限等级，留空默认为获取\n"
                                                     "  [@xxx] 指定被执行成员，留空默认为自己";
                            try {
                                send_group_message(groupID_int, responseMessage);
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (paramList[1] == "-get") {
                            try {
                                send_group_message(groupID_int,
                                                   "[CQ:at,qq=" + to_string(callerID_int) + "] 的权限等级为：" +
                                                   to_string(authLevel));
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (paramList[1] == "-set") {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数为 \"-set\" 时有效参数个数为：3");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数无法被识别");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    case 3 :
                        if (paramList[1] == "-h") {
                            try {
                                send_group_message(groupID_int, "参数错误：多余的第 2 个参数");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (paramList[1] == "-get") {
                            if (regex_match(paramList[2], subMatches, regex(R"(\[CQ:at,qq=(\d{5,20})\])"))) {
                                int64_t userID_int = strtol(subMatches[1].str().c_str(), nullptr, 10);
                                int32_t tempAuthLevel = privilege::group::GetUserAuthLevel(to_string(groupID_int),
                                                                                           userID_int, tempDatabase);
                                try {
                                    send_group_message(groupID_int,
                                                       "[CQ:at,qq=" + to_string(userID_int) + "] 的权限等级为：" +
                                                       to_string(tempAuthLevel));
                                } catch (ApiError &e) {
                                    logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                }
                            } else {
                                try {
                                    send_group_message(groupID_int, "参数错误：第 2 个参数类型或范围错误");
                                } catch (ApiError &e) {
                                    logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                }
                            }
                        } else if (paramList[1] == "-set") {
                            try {
                                send_group_message(groupID_int, "第 1 个参数为 \"-set\" 时有效参数个数为：3");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数无法被识别");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    case 4 :
                        if (paramList[1] == "-h") {
                            try {
                                send_group_message(groupID_int, "参数错误：多余的第 2、3 个参数");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (paramList[1] == "-get") {
                            try {
                                send_group_message(groupID_int, "参数错误：多余的第 3 个参数");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (paramList[1] == "-set") {
                            if (regex_match(paramList[2], subMatches, regex(R"((\d{1,3}))"))) {
                                int setAuthLevel = strtol(subMatches[1].str().c_str(), nullptr, 10);
                                if (setAuthLevel < 0 || setAuthLevel >= authLevel) {
                                    try {
                                        send_group_message(groupID_int, "参数错误：第 2 个参数范围错误或设置比自身权限相等或更高");
                                    } catch (ApiError &e) {
                                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                    }
                                } else if (regex_match(paramList[3], subMatches, regex(R"(\[CQ:at,qq=(\d{5,20})\])"))) {
                                    int64_t userID_int = strtol(subMatches[1].str().c_str(), nullptr, 10);
                                    int32_t tempAuthLevel = privilege::group::GetUserAuthLevel(to_string(groupID_int),
                                                                                               userID_int,
                                                                                               tempDatabase);
                                    if (authLevel >= AUTH_MANAGER) {
                                        if (authLevel > tempAuthLevel) {
                                            auto tempMemberDoc = tempDatabase.collection(
                                                    to_string(groupID_int)).find_one(
                                                    document{} << "userID" << userID_int << finalize);
                                            tempDatabase.collection(to_string(groupID_int)).update_one(
                                                    tempMemberDoc->view(),
                                                    document{} << "$set" << open_document << "authLevel" << setAuthLevel
                                                               << close_document << finalize);
                                            try {
                                                send_group_message(groupID_int,
                                                                   "[CQ:at,qq=" + to_string(userID_int) +
                                                                   "] 的权限等级被设置为：" +
                                                                   to_string(setAuthLevel));
                                            } catch (ApiError &e) {
                                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                            }
                                        } else {
                                            try {
                                                send_group_message(groupID_int,
                                                                   "权限错误：无法对权限相等或更高的成员执行此命令：" + to_string(authLevel) +
                                                                   " <= " + to_string(tempAuthLevel));
                                            } catch (ApiError &e) {
                                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                            }
                                        }
                                    } else {
                                        try {
                                            send_group_message(groupID_int,
                                                               "权限错误：没有足够的权限使用该命令，至少需要：" + to_string(AUTH_MANAGER));
                                        } catch (ApiError &e) {
                                            logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                        }
                                    }
                                } else {
                                    try {
                                        send_group_message(groupID_int, "参数错误：第 3 个参数范围或类型错误");
                                    } catch (ApiError &e) {
                                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                    }
                                }
                            } else {
                                try {
                                    send_group_message(groupID_int, "参数错误：第 2 个参数类型或范围错误");
                                } catch (ApiError &e) {
                                    logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                }
                            }
                        } else {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数无法被识别");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    default:
                        try {
                            send_group_message(groupID_int, "参数错误：参数个数 \"" + to_string(paramList.size() - 1) + "\" 错误，应为 [0-3]");
                        } catch (ApiError &e) {
                            logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                        }
                        break;
                }
            }

            void CommandFeature(int64_t groupID_int, int64_t callerID_int, const vector<string> &paramList, int32_t authLevel,
                                const mongocxx::database &tempDatabase, const vector<keyValue> &enabledFeatures_vec) {
                smatch subMatches;
                switch (paramList.size()) {
                    case 2:
                        if (paramList[1] == "-h") {
                            string responseMessage = "#feature指令帮助：\n"
                                                     "  {xxx} 要查看|设置的属性\n"
                                                     "  {xxx} 仅当设置属性时使用，内容为要设置的数据\n"
                                                     "  [@xxx] 指定被执行成员，留空默认为自己";
                            try {
                                send_group_message(groupID_int, responseMessage);
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (regex_match(paramList[1], subMatches, regex(R"((.{1,128}))"))) {
                            string tempFeature = subMatches[1];
                            bool isExist = false;
                            for (const auto &feature : enabledFeatures_vec) {
                                if (feature.stringKey == tempFeature) {
                                    isExist = true;
                                    auto tempMemberDoc = tempDatabase.collection(to_string(groupID_int)).find_one(document{} << "userID" << callerID_int << finalize);
                                    if (feature.stringValue == "int32_t") {
                                        int32_t tempValue = tempMemberDoc->view()[tempFeature].get_int32().value;
                                        send_group_message(groupID_int, "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：" + to_string(tempValue) + " (int32_t)");
                                    } else if (feature.stringValue == "int64_t") {
                                        int64_t tempValue = tempMemberDoc->view()[tempFeature].get_int64().value;
                                        send_group_message(groupID_int, "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：" + to_string(tempValue) + " (int64_t)");
                                    } else if (feature.stringValue == "double") {
                                        double tempValue = tempMemberDoc->view()[tempFeature].get_double().value;
                                        send_group_message(groupID_int, "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：" + to_string(tempValue) + " (double)");
                                    } else if (feature.stringValue == "utf_8") {
                                        string tempValue = "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：";
                                        stringstream tempSS;
                                        tempSS << tempMemberDoc->view()[tempFeature].get_utf8().value;
                                        tempValue += tempSS.str() + " (string)";
                                        send_group_message(groupID_int, tempValue);
                                    }
                                    break;
                                }
                            }
                            if (!isExist) {
                                try {
                                    send_group_message(groupID_int, "数据库错误：没有名为 " + tempFeature + " 的属性");
                                } catch (ApiError &e) {
                                    logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                }
                            }
                        } else {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数无法被识别");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    case 3:
                        if (paramList[1] == "-h") {
                            try {
                                send_group_message(groupID_int, "参数错误：多余的第 2 个参数");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (regex_match(paramList[1], subMatches, regex(R"((.{1,128}))"))) {
                            string tempFeature = subMatches[1];
                            if (authLevel >= AUTH_OWNER) {
                                bool isExist = false;
                                if (regex_match(paramList[2], subMatches, regex(R"(\[CQ:at,qq=(\d{5,20})\])"))) {
                                    int64_t userID_int = strtoll(subMatches[1].str().c_str(), nullptr, 10);
                                    for (const auto &feature : enabledFeatures_vec) {
                                        if (feature.stringKey == tempFeature) {
                                            isExist = true;
                                            auto tempMemberDoc = tempDatabase.collection(to_string(groupID_int)).find_one(document{} << "userID" << callerID_int << finalize);
                                            if (feature.stringValue == "int32_t") {
                                                int32_t tempValue = tempMemberDoc->view()[tempFeature].get_int32().value;
                                                send_group_message(groupID_int, "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：" + to_string(tempValue) + " (int32_t)");
                                            } else if (feature.stringValue == "int64_t") {
                                                int64_t tempValue = tempMemberDoc->view()[tempFeature].get_int64().value;
                                                send_group_message(groupID_int, "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：" + to_string(tempValue) + " (int64_t)");
                                            } else if (feature.stringValue == "double") {
                                                double tempValue = tempMemberDoc->view()[tempFeature].get_double().value;
                                                send_group_message(groupID_int, "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：" + to_string(tempValue) + " (double)");
                                            } else if (feature.stringValue == "utf_8") {
                                                string tempValue = "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性对应的数据为：";
                                                stringstream tempSS;
                                                tempSS << tempMemberDoc->view()[tempFeature].get_utf8().value;
                                                tempValue += tempSS.str() + " (string)";
                                                send_group_message(groupID_int, tempValue);
                                            }
                                            break;
                                        }
                                    }
                                } else if (regex_match(paramList[2], subMatches, regex(R"((.{1,128}))"))) {
                                    string tempValue_str = subMatches[1];
                                    for (const auto &feature : enabledFeatures_vec) {
                                        if (feature.stringKey == tempFeature) {
                                            isExist = true;
                                            auto tempMemberDoc = tempDatabase.collection(to_string(groupID_int)).find_one(document{} << "userID" << callerID_int << finalize);
                                            if (feature.stringValue == "int32_t") {
                                                int32_t tempValue_int = strtol(tempValue_str.c_str(), nullptr, 10);
                                                tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_int << finalize);
                                                send_group_message(groupID_int,
                                                                   "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + to_string(tempValue_int) + " (int32_t)");
                                            } else if (feature.stringValue == "int64_t") {
                                                int64_t tempValue_int = tempMemberDoc->view()[tempFeature].get_int64().value;
                                                tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_int << finalize);
                                                send_group_message(groupID_int,
                                                                   "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + to_string(tempValue_int) + " (int64_t)");
                                            } else if (feature.stringValue == "double") {
                                                double tempValue_double = tempMemberDoc->view()[tempFeature].get_double().value;
                                                tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_double << finalize);
                                                send_group_message(groupID_int,
                                                                   "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + to_string(tempValue_double) + " (double)");
                                            } else if (feature.stringValue == "utf_8") {
                                                tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_str << finalize);
                                                send_group_message(groupID_int, "[CQ:at,qq=" + to_string(callerID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + tempValue_str + " (string)");
                                            }
                                            break;
                                        }
                                    }
                                } else {
                                    try {
                                        send_group_message(groupID_int, "参数错误：第 2 个参数无法被识别");
                                    } catch (ApiError &e) {
                                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                    }
                                }
                                if (!isExist) {
                                    try {
                                        send_group_message(groupID_int, "数据库错误：没有名为 " + tempFeature + " 的属性");
                                    } catch (ApiError &e) {
                                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                    }
                                }
                            } else {
                                try {
                                    send_group_message(groupID_int,
                                                       "权限错误：没有足够的权限使用该命令，至少需要：" + to_string(AUTH_OWNER));
                                } catch (ApiError &e) {
                                    logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                }
                            }
                        } else {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数无法被识别");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    case 4:
                        if (paramList[1] == "-h") {
                            try {
                                send_group_message(groupID_int, "参数错误：多余的第 2、3 个参数");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        } else if (regex_match(paramList[1], subMatches, regex(R"((.{1,128}))"))) {
                            string tempFeature = subMatches[1];
                            if (authLevel >= AUTH_OWNER) {
                                bool isExist = false;
                                if (regex_match(paramList[2], subMatches, regex(R"((.{1,128}))"))) {
                                    string tempValue_str = subMatches[1];
                                    if (regex_match(paramList[3], subMatches, regex(R"(\[CQ:at,qq=(\d{5,20})\])"))) {
                                        int64_t userID_int = strtoll(subMatches[1].str().c_str(), nullptr, 10);
                                        for (const auto &feature : enabledFeatures_vec) {
                                            if (feature.stringKey == tempFeature) {
                                                isExist = true;
                                                auto tempMemberDoc = tempDatabase.collection(to_string(groupID_int)).find_one(document{} << "userID" << userID_int << finalize);
                                                if (feature.stringValue == "int32_t") {
                                                    int32_t tempValue_int = strtol(tempValue_str.c_str(), nullptr, 10);
                                                    tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_int << finalize);
                                                    send_group_message(groupID_int,
                                                                       "[CQ:at,qq=" + to_string(userID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + to_string(tempValue_int) + " (int32_t)");
                                                } else if (feature.stringValue == "int64_t") {
                                                    int64_t tempValue_int = tempMemberDoc->view()[tempFeature].get_int64().value;
                                                    tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_int << finalize);
                                                    send_group_message(groupID_int,
                                                                       "[CQ:at,qq=" + to_string(userID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + to_string(tempValue_int) + " (int64_t)");
                                                } else if (feature.stringValue == "double") {
                                                    double tempValue_double = tempMemberDoc->view()[tempFeature].get_double().value;
                                                    tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_double << finalize);
                                                    send_group_message(groupID_int,
                                                                       "[CQ:at,qq=" + to_string(userID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + to_string(tempValue_double) + " (double)");
                                                } else if (feature.stringValue == "utf_8") {
                                                    tempDatabase.collection(to_string(groupID_int)).update_one(tempMemberDoc->view(), document{} << tempFeature << tempValue_str << finalize);
                                                    send_group_message(groupID_int, "[CQ:at,qq=" + to_string(userID_int) + "] 的 " + tempFeature + " 属性更新数据为：" + tempValue_str + " (string)");
                                                }
                                                break;
                                            }
                                        }
                                    } else {
                                        try {
                                            send_group_message(groupID_int, "参数错误：第 3 个参数类型或范围错误");
                                        } catch (ApiError &e) {
                                            logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                        }
                                    }
                                } else {
                                    try {
                                        send_group_message(groupID_int, "参数错误：第 2 个参数无法被识别");
                                    } catch (ApiError &e) {
                                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                    }
                                }
                                if (!isExist) {
                                    try {
                                        send_group_message(groupID_int, "数据库错误：没有名为 " + tempFeature + " 的属性");
                                    } catch (ApiError &e) {
                                        logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                    }
                                }
                            } else {
                                try {
                                    send_group_message(groupID_int,
                                                       "权限错误：没有足够的权限使用该命令，至少需要：" + to_string(AUTH_OWNER));
                                } catch (ApiError &e) {
                                    logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                                }
                            }
                        } else {
                            try {
                                send_group_message(groupID_int, "参数错误：第 1 个参数无法被识别");
                            } catch (ApiError &e) {
                                logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                            }
                        }
                        break;
                    default:
                        try {
                            send_group_message(groupID_int, "参数错误：参数个数 \"" + to_string(paramList.size() - 1) + "\" 错误，应为 [2-3]");
                        } catch (ApiError &e) {
                            logging::warning("群聊", "群聊消息发送失败, 错误码: " + to_string(e.code));
                        }
                        break;
                }
            }
        }
    }

    namespace single {
        namespace manage {

        }
    }
}